home *** CD-ROM | disk | FTP | other *** search
/ PC World 2006 November / PCWorld_2006-11_cd.bin / domacnost a kancelar / findgraph / fgraph.exe / {app} / ApprSource / ExpPow.cpp next >
C/C++ Source or Header  |  2004-07-02  |  9KB  |  376 lines

  1. /******************************************************************************
  2.  * Plug-In DLL Example and Template
  3.  * for use with C/C++
  4.  *
  5.  * Compile DLL with any name.
  6.  * Place it in  the program FindGraph subfolder "Appr".
  7.  * Next functions must be exported:
  8.  *        MaxOfFactors
  9.  *        Prepare
  10.  *        CalcInPoint
  11.  *        FunctionTitle
  12.  *        FunctionName 
  13.  *        FunctionString
  14.  *        ParamInfo
  15.  * 
  16.  * To test DLL, restart FundGraph, 
  17.  * start The Wizard of approximation,
  18.  * on step 2 select 'User defined function'.
  19.  * If all right, on step 3 your function will appear in list.
  20.  * 
  21.  ******************************************************************************/
  22.  
  23.  
  24. #include <windows.h>
  25. #include <tchar.h>
  26. #include <math.h>
  27. #include "exppow.h"
  28.  
  29.  
  30. #include <stdio.h>
  31.  
  32.  
  33. // 
  34. #pragma comment(linker,"/MERGE:.rdata=.text")
  35. #pragma comment(linker,"/FILEALIGN:512 /SECTION:.text,EWRX /IGNORE:4078")
  36.  
  37. //////////////////////////////////////////////////////////////////////////////////
  38.  
  39.  
  40. HINSTANCE g_hInstance=NULL;
  41. BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
  42. {
  43.     switch (ul_reason_for_call)
  44.     {
  45.         case DLL_PROCESS_ATTACH:
  46.              g_hInstance = (HINSTANCE )hModule;
  47.              break;
  48.         case DLL_PROCESS_DETACH:
  49.              break;
  50.     }
  51.      return TRUE;
  52. }
  53.  
  54.  
  55.  
  56.  
  57. ////////////////////////////////////////////////////////////////////////////////////////////////////
  58. #define N_FACTORS 10 
  59. #define aa(i,j) pfs[i*nn+j]
  60.  
  61. // 2 linear equations
  62. // Input
  63. // pfs = matrix [2,3]
  64. // Output
  65. // pfu - vector [2]
  66. //
  67. void CalcEquGauss2(double *pfs, double *pfu)
  68. {
  69.   int    n = 1,
  70.         nn = n+2;
  71.  
  72.     
  73.     double d = aa(0,0) * aa(1,1) - aa(0,1)*aa(1,0);
  74.     if (d == 0.) 
  75.     {
  76.         pfu[1] = 0.;
  77.         pfu[0] = (aa(0,0) != 0.) ? aa(0,2) / aa(0,0) : 0.;
  78.     }
  79.     else
  80.     {
  81.         pfu[0] = (aa(1,1)*aa(0,2) - aa(0,1)*aa(1,2)) / d;
  82.         pfu[1] = (aa(0,0)*aa(1,2) - aa(1,0)*aa(0,2)) / d;
  83.     }
  84. }
  85.  
  86.  
  87. // Error of calculus
  88. //
  89. double CalcError(double *pfU, double *pfV, int nPoints, 
  90.                  double *pfFactors, int nFactors)
  91. {
  92.     if (nPoints  <= 0)
  93.         return 0.;
  94.     double fError = 0.;
  95.     for (int id=0; id < nPoints; id++ )
  96.     {
  97.         double u = pfU[id],
  98.                v = pfV[id],
  99.                v1= CalcInPoint(u, pfFactors, nFactors);
  100.         fError += (v1-v)*(v1-v);
  101.     }
  102.     fError = sqrt(fError/nPoints);
  103.     return fError;
  104. }
  105.  
  106. ////////////////////////////////////////////////////////////////////////////////////////////////////
  107. //
  108. // Return the number of factors (see function 'Prepare')
  109. // use to memory allocate for pfFactors
  110. //
  111.  
  112. //extern "C" bool __declspec( dllexport ) __stdcall TransFromDisk(char *Base, char *Disk);
  113.  
  114.  
  115. int __declspec(dllexport) __stdcall MaxOfFactors()
  116. {
  117.     return N_FACTORS;
  118. }
  119.  
  120.  
  121. //
  122. // Prepare approximation function V(U) = Function(U)
  123. //     V(U) = V0 + exp(a*(U-U0))*Pow((U-U0), b)
  124. // Input:
  125. // Array of points (U,V)
  126. //        fMinU, fMaxU - limits of U 
  127. //        fMinV, fMaxV - limits of V 
  128. //        pfU, pfV - array of nPoints points (U,V)
  129. //        pfW         - weight of point
  130. //      nPoints     - number of points in array 
  131. // Parameters:
  132. //        pfParams - array of parameters
  133. //        U0 = pfParams[0]    
  134. //        V0 = pfParams[1]    
  135. //      nParams  - number of parameters in array 
  136. //
  137. // Output:
  138. // Array of factors is calculated.
  139. // This factors will be used in function CalcInPoint(U, pfFactors)
  140. //        pfFactors - array of factors, defined by user
  141. //        Notes: pfFactors[*pnFactors-1] = Error of calculus
  142. //      nFactors:
  143. //            Input  - maximum possible number of factors in array 
  144. //
  145. // return: number of factors if success, else error code
  146. //
  147. int __declspec(dllexport) __stdcall Prepare (double fMinU, double fMaxU, double fMinV, double fMaxV,
  148.                double *pfU, double *pfV, double *pfW, int nPoints, 
  149.                double *pfParams , int nParams ,
  150.                double *pfFactors, int nFactors)
  151. {
  152.     int nResult = 0;
  153.     if (nPoints < 2) // not enough points
  154.         return -1;
  155.  
  156.     if (nFactors < N_FACTORS) // not enough memory for result
  157.         return -2;
  158.  
  159.  
  160.     int    
  161.            nAppr = 1,
  162.            nn = nAppr + 2,
  163.            ns =(nAppr+1)*(nn+1);
  164.  
  165.     double fU0 = fMinU,
  166.            fV0 = fMinV;
  167.     if (nParams > 0) fU0 = pfParams[0];
  168.     if (nParams > 1) fV0 = pfParams[1];
  169.  
  170.  
  171.     double 
  172.            *pfs,
  173.            *pfu;
  174.     // use: aa(i,j) == pfs[i*nn+j]
  175.  
  176.  
  177.     pfu = new double[nAppr+1];// calced coeff 
  178.     pfs = new double[ns];
  179.     memset(pfs, 0, ns*sizeof(double));
  180.  
  181.  
  182.         int  nSum = 0; // point with U>0, V>0
  183.         for (int id=0; id < nPoints; id++ )
  184.         {
  185.             double u = pfU[id] - fU0,
  186.                    v = pfV[id] - fV0;
  187.             if  (u > 0. && v > 0.)
  188.             {
  189.                 double lu = log(u),
  190.                        lv = log(v);
  191.  
  192.                 aa(0,0) +=  u* u;
  193.                 aa(0,1) +=  u*lu;
  194.                 aa(0,2) +=  u*lv;
  195.                 aa(1,0) += lu* u;
  196.                 aa(1,1) += lu*lu;
  197.                 aa(1,2) += lu*lv;
  198.  
  199.                 nSum++;
  200.             }
  201.         }
  202.         if (nSum >= 2)
  203.         {
  204.             CalcEquGauss2(pfs, pfu);
  205.             nResult         = N_FACTORS;
  206.             
  207.             pfFactors[0] = nSum;
  208.             pfFactors[1] = fMinU; pfFactors[2] = fMaxU; // Unused now - reserved
  209.             pfFactors[3] = fMinV; pfFactors[4] = fMaxV; // Unused now - reserved
  210.             pfFactors[4] = 0; // Unused now - reserved
  211.             pfFactors[5] = fU0;
  212.             pfFactors[6] = fV0;
  213.             pfFactors[7] = pfu[0]; // a
  214.             pfFactors[8] = pfu[1]; // b
  215.  
  216.             pfFactors[N_FACTORS-1] = CalcError(pfU, pfV, nPoints, pfFactors, nFactors); 
  217.         }
  218.  
  219.  
  220.  
  221.     delete [] pfu;
  222.     delete [] pfs;
  223.     return nResult;
  224. }
  225.  
  226. // Calculate value V = Function(fU)
  227. // Input:
  228. //        fU
  229. //        pfFactors - array of factors, prepared in finction Prepare()
  230. //      pnFactors: - number of factors in array 
  231. //
  232. // return: value calculated
  233. //
  234. double __declspec(dllexport) __stdcall CalcInPoint(double fU, 
  235.                                          double *pfFactors, int nFactors)
  236. {
  237.     double fV = 0.;
  238.     if (nFactors < N_FACTORS)
  239.         return  0.;
  240.     double 
  241.             U0 = pfFactors[5],
  242.             V0 = pfFactors[6],
  243.             a  = pfFactors[7],
  244.             b  = pfFactors[8],
  245.             U  = fU - U0;
  246.     if  (U <= 0.)
  247.         return 0.;
  248.     fV = V0 + exp(a*U)*pow(U, b);
  249.  
  250.     return fV;
  251. }
  252.  
  253.  
  254. // Fill information string with name of approximation method
  255. // It is used in FindGraph <Master of approximations page 2><list of user defined functions>
  256. // for example - "User's ExpPow"
  257. // Input:
  258. //        pstr - buffer TCHAR
  259. //      nMaxLength - maximum buffer length
  260. //
  261. // Output:
  262. //        pstr - name of approximation method
  263. //
  264. // return: string length if success, else -1
  265. //
  266. int __declspec(dllexport) __stdcall FunctionTitle(LPTSTR pstr, int nMaxLength) 
  267. {
  268.     if (pstr==0)
  269.         return -1;
  270.     lstrcpyn(pstr, TEXT(" Y = Exp(a*X)*Pow(x,b)   (see sample in directory \'ApprSource\')"), nMaxLength);
  271.     return lstrlen(pstr);
  272. }
  273.  
  274.  
  275.  
  276. // Fill information string with name of approximation function
  277. // for example - "V(U) = V0 + Exp(a*(U-U0))*Pow((U-U0), b)"
  278. // It is used in FindGraph <Master of approximations page 3><Function description>
  279. // Input:
  280. //        pstr - buffer TCHAR
  281. //      nMaxLength - maximum buffer length
  282. //
  283. // Output:
  284. //        pstr - name of approximation function
  285. //
  286. // return: string length if success, else -1
  287. //
  288. int __declspec(dllexport) __stdcall FunctionName(LPTSTR pstr, int nMaxLength) 
  289. {
  290.     if (pstr==0)
  291.         return -1;
  292.     lstrcpyn(pstr, TEXT("f(U) = V0 + Exp(a*(U-U0))*Pow((U-U0), b)"), nMaxLength);
  293.     return lstrlen(pstr);
  294. }
  295.  
  296.  
  297.  
  298. // Fill information string with formula of calculated function f(U) = Formula()
  299. // for example - "V(U) = 1. + Exp(2*(U-3.))*Pow((U-3.), 4)"
  300. // It is used in FindGraph <Master of approximations pages 4 and 5>
  301. // Input:
  302. //        pstr - buffer TCHAR
  303. //      nMaxLength - maximum buffer length
  304. //        pfFactors - array of factors, prepared in finction Prepare()
  305. //      pnFactors: - number of factors in array 
  306. //
  307. // Output:
  308. // pstr - string of calculated function f(U)
  309. //
  310. // return: string length if success, else -1
  311. //
  312. int __declspec(dllexport) __stdcall FunctionString(double *pfFactors, int nFactors,
  313.                                          LPTSTR pstr, int nMaxLength) 
  314. {
  315.     if (pstr==0)
  316.         return -1;
  317.     if (nFactors < N_FACTORS)
  318.         return -2;
  319.  
  320.     TCHAR  sz[256];
  321.     double 
  322.             U0 = pfFactors[5],
  323.             V0 = pfFactors[6],
  324.             a  = pfFactors[7],
  325.             b  = pfFactors[8];
  326.  
  327.     sprintf(sz, TEXT("f(U) = %4.4g + Exp(%4.2f*(U-%4.4g))*Pow((U-%4.4g), %4.2f)"), V0, a, U0, U0, b);
  328.     lstrcpyn(pstr, sz, nMaxLength);
  329.     return lstrlen(pstr);
  330. }
  331.  
  332.  
  333.  
  334. // Fill information string with name of parameter and it's default value
  335. // It is used in FindGraph <Master of approximations page 3>
  336. // Input:
  337. //      nParam - number of edit box in page 3
  338. //                 1, 2, 3, 4
  339. //               see list of pfParams in function 'Prepare'
  340. //        pstr - buffer TCHAR
  341. //      nMaxLength - maximum buffer length
  342. //
  343. // Output:
  344. //        pstr - name of parameter[nParam]
  345. //      pfDefault - default value of parameter[nParam]
  346. //
  347. // return: string length if success, else -1
  348. //
  349. int __declspec(dllexport) __stdcall ParamInfo(int nParam, LPTSTR pstr, int nMaxLength, double *pfDefault) 
  350. {
  351.     if (pstr==0)
  352.         return -1;
  353.     switch (nParam)
  354.     {
  355.         case 1: 
  356.             lstrcpyn(pstr, TEXT("U0"), nMaxLength);
  357.             if (pfDefault != NULL)
  358.                *pfDefault = 0.;
  359.             break;
  360.         case 2: 
  361.             lstrcpyn(pstr, TEXT("V0"), nMaxLength);
  362.             if (pfDefault != NULL)
  363.                *pfDefault = 0.;
  364.             break;
  365.         case 3: 
  366.         case 4: 
  367.             lstrcpyn(pstr, TEXT("unused"), nMaxLength);
  368.             if (pfDefault != NULL)
  369.                *pfDefault = 0.;
  370.             break;
  371.         default: return -1;
  372.     }
  373. //*pfDefault = 10+nParam;
  374.     return lstrlen(pstr);
  375. }
  376.